0.1 Carregamento de um novo conjunto de dados no formato SMART

A primeira função que utilizaremos, carregar_dados_brutos_xlsx(), irá carregar a planilha de dados do SMART em formato excel. Essa função carrega um arquivo do tipo .xlsx e gerar automaticamente o arquivo backup nomeado como dados_brutos_SMART.rds na pasta data-raw. A função seguinte a ser utilizada, gerar_dados_completos_SMART() que irá carregar o arquivo dados_brutos_SMART.rds. Essa função foi escrita para carrega os dados e operar uma série de transformações para devolvê-lo mais próximo ao necessário para conduzir as análises. Como exemplo, utilizaremos o arquivo monitora_masto_aves_SMART.xlsx.

Antes de começar o carregamento dos dados é necessário carregar as funções necessárias utilizando o comando source().

# carregar as funções necessárias
source(here::here("R/carregar_dados_brutos_xlsx.R"))

source(here::here("R/gerar_dados_completos_SMART.R"))

Para carregar a nova base de dados, é importante que ela esteja salva na pasta data-raw do projeto Monitora. Para isso, basta manter a estrutura de pastas do projeto (veja o README do repositório). No corpo da função, deve ser informado o caminho para o arquivo (ex. nome da pasta, data-raw, e o nome do arquivo, monitora_masto_aves_2023_04_04.xlsx).

# carregar a base de dados do Monitora
dados_brutos_SMART <- carregar_dados_brutos_xlsx(
  dados = "data-raw/monitora_masto_aves_SMART.xlsx",
  sheet = 3 # indica a aba com a planilha a ser carregada
)

head(dados_brutos_SMART)
dplyr::glimpse(dados_brutos_SMART)
Rows: 53
Columns: 34
$ `CDUC (código da unidade de conservação)`     <lgl> …
$ `Local - Nome da Unidade de Conservação`      <chr> …
$ `Número da Estação Amostral`                  <dbl> …
$ `Nome da EA`                                  <lgl> …
$ `Esforço de amostragem tamanho da trilha (m)` <dbl> …
$ `data de início da amostragem`                <dttm> …
$ `data de término da amostragem`               <dttm> …
$ `Ano da amostragem`                           <dbl> …
$ `Estação do ano`                              <lgl> …
$ `Horário de início`                           <dttm> …
$ `Horário de término`                          <dttm> …
$ `Tempo de censo`                              <dttm> …
$ `Velocidade (km/h)`                           <dbl> …
$ `Condição Climática/Tempo`                    <chr> …
$ `ID Observadores`                             <chr> …
$ `ID líder`                                    <dbl> …
$ `Nome dos observadores`                       <chr> …
$ `Nome do líder`                               <chr> …
$ `ID observação`                               <chr> …
$ `Número do animal no guia`                    <dbl> …
$ classe                                        <lgl> …
$ ordem                                         <lgl> …
$ familia                                       <lgl> …
$ gênero                                        <chr> …
$ especie                                       <chr> …
$ `nome popular`                                <chr> …
$ `O que foi identificado`                      <chr> …
$ `Nº animais encontrados`                      <chr> …
$ `tinha mais?`                                 <chr> …
$ `distância da trilha (metros)`                <chr> …
$ `Número da próxima plaqueta`                  <chr> …
$ `Problema na amostragem?`                     <chr> …
$ Longitude                                     <dbl> …
$ Latitude                                      <dbl> …

Em seguida, usamos a função gerar_dados_completos_SMART().

# gerar dados completos
dados_completos_SMART <- gerar_dados_completos_SMART(dados_brutos_SMART)

head(dados_completos_SMART)
dplyr::glimpse(dados_completos_SMART)
Rows: 53
Columns: 20
$ nome_ea             <lgl> NA, NA, NA, NA, NA, NA, N…
$ n_visitas_repetidas <int> 1, 1, 1, 1, 1, 1, 1, 1, 1…
$ codigo_uc           <lgl> NA, NA, NA, NA, NA, NA, N…
$ categoria_uc        <fct> rds, rds, rds, rds, rds, …
$ nome_uc             <fct> rds_uatuma, rds_uatuma, r…
$ nome_uc_abv         <fct> noth, pene_supe, cryp, sa…
$ numero_ea           <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1…
$ data_amostragem     <dttm> 2023-06-14, 2023-06-14, …
$ estacao             <lgl> NA, NA, NA, NA, NA, NA, N…
$ ano                 <dbl> 2023, 2023, 2023, 2023, 2…
$ esforco_dia         <dbl> 4396, 4396, 4396, 4396, 4…
$ esforco_total       <dbl> 4396, 4396, 4396, 4396, 4…
$ nome_sp             <fct> nothocrax, penelope_super…
$ nome_sp_abv         <fct> noth, pene_supe, cryp, sa…
$ validacao           <fct> especie, especie, genero,…
$ distancia           <dbl> 1.2, 2.6, 6.1, 2.1, 6.4, …
$ tamanho_grupo       <dbl> 1, 1, 2, 4, 1, 1, 2, 1, 2…
$ velocidade_km_h     <dbl> 24381.46, 24381.46, 24381…
$ tempo_censo         <drtn> 4.327222 hours, 4.327222…
$ numero_observadores <dbl> 4, 4, 4, 4, 4, 4, 4, 4, 4…

Para garantir a reprodutibilidade dos códigos produzidos em versões atualizadas da base de dados do Monitora, é importante tomar alguns cuidados. O primeiro e mais importante cuidado é manter a consistência dos nomes, da ordem e do número de colunas em versões atualizadas da base de dados do Monitora. Além de carregar os dados, a função carregar_dados_completos() aplica uma série de transformações nas colunas. Seus nomes são alterados, e a essas são atribuídos tipos apropriados (data, caracter, fator, inteiro e numérico), linhas são eliminadas e novas colunas são geradas. Qualquer alteração no número de colunas, nos seus nomes ou na sua ordem levará a um mal funcionamento da função de transformação dos dados.

Outros aspectos importantes incluem:

A partir de agora os dados estão prontos para serem explorados, ou mesmo filtrados e transformados para o formato do pacote Distance para análise de densidade. Por exemplo, filtrar os dados para a UC cujos os dados foram introduzidos a partir do SMART:

# carregar função de filtragem dos dados
source(here::here("R/filtrar_dados.R"))

# filtrar dados por Unidade de Conservação e por espécie
dados_filtrados_SMART <- filtrar_dados(
  dados = dados_completos_SMART,
  nome_ucs = "rds_uatuma"
)

head(dados_filtrados_SMART)
str(dados_filtrados_SMART)
tibble [53 × 20] (S3: tbl_df/tbl/data.frame)
 $ nome_ea            : logi [1:53] NA NA NA NA NA NA ...
 $ n_visitas_repetidas: int [1:53] 1 1 1 1 1 1 1 1 1 1 ...
 $ codigo_uc          : logi [1:53] NA NA NA NA NA NA ...
 $ categoria_uc       : Factor w/ 1 level "rds": 1 1 1 1 1 1 1 1 1 1 ...
 $ nome_uc            : Factor w/ 1 level "rds_uatuma": 1 1 1 1 1 1 1 1 1 1 ...
 $ nome_uc_abv        : Factor w/ 11 levels "call_vier","chir_ssat",..: 7 9 4 10 5 6 11 3 1 2 ...
 $ numero_ea          : num [1:53] 1 1 1 1 1 1 1 1 1 1 ...
 $ data_amostragem    : POSIXct[1:53], format: "2023-06-14" ...
 $ estacao            : logi [1:53] NA NA NA NA NA NA ...
 $ ano                : num [1:53] 2023 2023 2023 2023 2023 ...
 $ esforco_dia        : num [1:53] 4396 4396 4396 4396 4396 ...
 $ esforco_total      : num [1:53] 4396 4396 4396 4396 4396 ...
 $ nome_sp            : Factor w/ 11 levels "callicebus_vierai",..: 7 9 4 10 5 6 11 3 1 2 ...
 $ nome_sp_abv        : Factor w/ 11 levels "call_vier","chir_ssat",..: 7 9 4 10 5 6 11 3 1 2 ...
 $ validacao          : Factor w/ 2 levels "especie","genero": 1 1 2 2 1 2 1 1 1 1 ...
 $ distancia          : num [1:53] 1.2 2.6 6.1 2.1 6.4 0 4 8 0 3 ...
 $ tamanho_grupo      : num [1:53] 1 1 2 4 1 1 2 1 2 4 ...
 $ velocidade_km_h    : num [1:53] 24381 24381 24381 24381 24381 ...
 $ tempo_censo        : 'difftime' num [1:53] 4.32722222222222 4.32722222222222 4.32722222222222 4.32722222222222 ...
  ..- attr(*, "units")= chr "hours"
 $ numero_observadores: num [1:53] 4 4 4 4 4 4 4 4 4 4 ...

Agora, podemos contar o número de observações validadas:

# carregar a função de contagem das observações validadas
source(here::here("R/contar_n_obs_validadas.R"))

# contar observações validadas ao nível de espécie
n_obs_validadas <- contar_n_obs_validadas(dados_filtrados_SMART)
n_obs_validadas

Vamos selecionar uma espécie da RDS Uatumã para então transformar os dados para o formato de análise do pacote Distance. Primeiro vamos avaliar qual foi a espécie mais abundante:

# carregar a função para contar número de observações por espécie e plotar os dados
source(here::here("R/contar_n_obs_sp.R"))
source(here::here("R/plotar_n_obs_sp_interativo.R"))

# contar o número de observações por espécie
n_obs_sp <- contar_n_obs_sp(dados_filtrados_SMART)
n_obs_sp

# plotar o número de observações por espécie
plotar_n_obs_sp_interativo(n_obs_sp)
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio

A espécie mais abundante foi Crypturellus sp. Vamos filtrar os dados somente para esse espécie:

dados_filtrados_crypt_SMART <- filtrar_dados(
  dados = dados_filtrados_SMART,
  nome_sps = "crypturellus"
)

head(dados_filtrados_crypt_SMART)
str(dados_filtrados_crypt_SMART)
tibble [9 × 20] (S3: tbl_df/tbl/data.frame)
 $ nome_ea            : logi [1:9] NA NA NA NA NA NA ...
 $ n_visitas_repetidas: int [1:9] 1 1 1 1 1 1 1 1 1
 $ codigo_uc          : logi [1:9] NA NA NA NA NA NA ...
 $ categoria_uc       : Factor w/ 1 level "rds": 1 1 1 1 1 1 1 1 1
 $ nome_uc            : Factor w/ 1 level "rds_uatuma": 1 1 1 1 1 1 1 1 1
 $ nome_uc_abv        : Factor w/ 11 levels "call_vier","chir_ssat",..: 4 4 4 4 4 4 4 4 4
 $ numero_ea          : num [1:9] 1 1 1 1 1 1 1 1 1
 $ data_amostragem    : POSIXct[1:9], format: "2023-06-14" ...
 $ estacao            : logi [1:9] NA NA NA NA NA NA ...
 $ ano                : num [1:9] 2023 2023 2023 2023 2023 ...
 $ esforco_dia        : num [1:9] 4396 4396 4396 4396 4396 ...
 $ esforco_total      : num [1:9] 4396 4396 4396 4396 4396 ...
 $ nome_sp            : Factor w/ 11 levels "callicebus_vierai",..: 4 4 4 4 4 4 4 4 4
 $ nome_sp_abv        : Factor w/ 11 levels "call_vier","chir_ssat",..: 4 4 4 4 4 4 4 4 4
 $ validacao          : Factor w/ 2 levels "especie","genero": 2 2 2 2 2 2 2 2 2
 $ distancia          : num [1:9] 6.1 1.3 6 9 13 1 17 1 2
 $ tamanho_grupo      : num [1:9] 2 1 3 3 1 4 2 2 3
 $ velocidade_km_h    : num [1:9] 24381 24381 24381 24381 24381 ...
 $ tempo_censo        : 'difftime' num [1:9] 4.32722222222222 4.32722222222222 4.32722222222222 4.32722222222222 ...
  ..- attr(*, "units")= chr "hours"
 $ numero_observadores: num [1:9] 4 4 4 4 4 4 4 4 4

Finalmente, vamos transformar os dados para o formato de análise:

# carregar função de transformação dos dados para o formato do pacote Distance
source(here::here("R/transformar_dados_formato_Distance.R"))

# transformar dados para o formato do pacote Distance
dados_transformados_SMART <- transformar_dados_formato_Distance(dados_filtrados_crypt_SMART)

head(dados_transformados_SMART)
dplyr::glimpse(dados_transformados_SMART)
Rows: 9
Columns: 12
$ Region.Label <fct> rds_uatuma, rds_uatuma, rds_uatu…
$ Area         <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0
$ Sample.Label <lgl> NA, NA, NA, NA, NA, NA, NA, NA, …
$ Effort       <dbl> 4396, 4396, 4396, 4396, 4396, 43…
$ sampling_day <dttm> 2023-06-14, 2023-06-14, 2023-06-…
$ distance     <dbl> 6.1, 1.3, 6.0, 9.0, 13.0, 1.0, …
$ season       <lgl> NA, NA, NA, NA, NA, NA, NA, NA, …
$ year         <dbl> 2023, 2023, 2023, 2023, 2023, 20…
$ size         <dbl> 2, 1, 3, 3, 1, 4, 2, 2, 3
$ cense_time   <drtn> 4.327222 hours, 4.327222 hours, …
$ speed        <dbl> 24381.46, 24381.46, 24381.46, 24…
$ object       <int> 1, 2, 3, 4, 5, 6, 7, 8, 9
LS0tCnRpdGxlOiAiRmx1eG8gZGUgdHJhYmFsaG8gcGFyYSBvIGNhcnJlZ2FtZW50byBkZSBub3ZvcyBkYWRvcyBubyBmb3JtYXRvIFNNQVJUIgphdXRob3I6IAotIEx1Y2lhbmEgRnVzaW5hdHRvIAotIFZpdG9yIEJvcmdlcy1Kw7puaW9yCmRhdGU6IENyaWFkbyBlbSAxNyBkZSBqdWxobyBkZSAyMDIzLCBhdHVhbGl6YWRvIGVtIGByIGZvcm1hdChTeXMudGltZSgpLCAnJWQgZGUgJUIKICBkZSAlWScpYApvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6IDUKICAgIHRvY19mbG9hdDogbm8KICAgIG51bWJlcl9zZWN0aW9uOiB5ZXMKICAgIGNvZGVfZm9sZGluZzogc2hvdwotLS0KCiMjICoqQ2FycmVnYW1lbnRvIGRlIHVtIG5vdm8gY29uanVudG8gZGUgZGFkb3Mgbm8gZm9ybWF0byBTTUFSVCoqIAoKQSBwcmltZWlyYSBmdW7Dp8OjbyBxdWUgdXRpbGl6YXJlbW9zLCBgY2FycmVnYXJfZGFkb3NfYnJ1dG9zX3hsc3goKWAsIGlyw6EgY2FycmVnYXIgYSBwbGFuaWxoYSBkZSBkYWRvcyBkbyBTTUFSVCBlbSBmb3JtYXRvIGV4Y2VsLiBFc3NhIGZ1bsOnw6NvIGNhcnJlZ2EgdW0gYXJxdWl2byBkbyB0aXBvIC54bHN4IGUgZ2VyYXIgYXV0b21hdGljYW1lbnRlIG8gYXJxdWl2byAqYmFja3VwKiBub21lYWRvIGNvbW8gYGRhZG9zX2JydXRvc19TTUFSVC5yZHNgIG5hIHBhc3RhIGBkYXRhLXJhd2AuIEEgZnVuw6fDo28gc2VndWludGUgYSBzZXIgdXRpbGl6YWRhLCBgZ2VyYXJfZGFkb3NfY29tcGxldG9zX1NNQVJUKClgIHF1ZSBpcsOhIGNhcnJlZ2FyIG8gYXJxdWl2byBgZGFkb3NfYnJ1dG9zX1NNQVJULnJkc2AuIEVzc2EgZnVuw6fDo28gZm9pIGVzY3JpdGEgcGFyYSBjYXJyZWdhIG9zIGRhZG9zIGUgb3BlcmFyIHVtYSBzw6lyaWUgZGUgdHJhbnNmb3JtYcOnw7VlcyBwYXJhIGRldm9sdsOqLWxvIG1haXMgcHLDs3hpbW8gYW8gbmVjZXNzw6FyaW8gcGFyYSBjb25kdXppciBhcyBhbsOhbGlzZXMuIENvbW8gZXhlbXBsbywgdXRpbGl6YXJlbW9zIG8gYXJxdWl2byBgbW9uaXRvcmFfbWFzdG9fYXZlc19TTUFSVC54bHN4YC4gIAoKQW50ZXMgZGUgY29tZcOnYXIgbyBjYXJyZWdhbWVudG8gZG9zIGRhZG9zIMOpIG5lY2Vzc8OhcmlvIGNhcnJlZ2FyIGFzIGZ1bsOnw7VlcyBuZWNlc3PDoXJpYXMgdXRpbGl6YW5kbyBvIGNvbWFuZG8gYHNvdXJjZSgpYC4KCmBgYHtyfQojIGNhcnJlZ2FyIGFzIGZ1bsOnw7VlcyBuZWNlc3PDoXJpYXMKc291cmNlKGhlcmU6OmhlcmUoIlIvY2FycmVnYXJfZGFkb3NfYnJ1dG9zX3hsc3guUiIpKQoKc291cmNlKGhlcmU6OmhlcmUoIlIvZ2VyYXJfZGFkb3NfY29tcGxldG9zX1NNQVJULlIiKSkKYGBgCgpQYXJhIGNhcnJlZ2FyIGEgbm92YSBiYXNlIGRlIGRhZG9zLCDDqSBpbXBvcnRhbnRlIHF1ZSBlbGEgZXN0ZWphIHNhbHZhIG5hIHBhc3RhIGBkYXRhLXJhd2AgZG8gcHJvamV0byBNb25pdG9yYS4gUGFyYSBpc3NvLCBiYXN0YSBtYW50ZXIgYSBlc3RydXR1cmEgZGUgcGFzdGFzIGRvIHByb2pldG8gKHZlamEgbyBSRUFETUUgZG8gcmVwb3NpdMOzcmlvKS4gTm8gY29ycG8gZGEgZnVuw6fDo28sIGRldmUgc2VyIGluZm9ybWFkbyBvIGNhbWluaG8gcGFyYSBvIGFycXVpdm8gKGV4LiBub21lIGRhIHBhc3RhLCBgZGF0YS1yYXdgLCBlIG8gbm9tZSBkbyBhcnF1aXZvLCBgbW9uaXRvcmFfbWFzdG9fYXZlc18yMDIzXzA0XzA0Lnhsc3hgKS4KCmBgYHtyLCB3YXJuaW5nPUZBTFNFfQojIGNhcnJlZ2FyIGEgYmFzZSBkZSBkYWRvcyBkbyBNb25pdG9yYQpkYWRvc19icnV0b3NfU01BUlQgPC0gY2FycmVnYXJfZGFkb3NfYnJ1dG9zX3hsc3goCiAgZGFkb3MgPSAiZGF0YS1yYXcvbW9uaXRvcmFfbWFzdG9fYXZlc19TTUFSVC54bHN4IiwKICBzaGVldCA9IDMgIyBpbmRpY2EgYSBhYmEgY29tIGEgcGxhbmlsaGEgYSBzZXIgY2FycmVnYWRhCikKCmhlYWQoZGFkb3NfYnJ1dG9zX1NNQVJUKQpkcGx5cjo6Z2xpbXBzZShkYWRvc19icnV0b3NfU01BUlQpCmBgYAoKRW0gc2VndWlkYSwgdXNhbW9zIGEgZnVuw6fDo28gYGdlcmFyX2RhZG9zX2NvbXBsZXRvc19TTUFSVCgpYC4gCgpgYGB7cn0KIyBnZXJhciBkYWRvcyBjb21wbGV0b3MKZGFkb3NfY29tcGxldG9zX1NNQVJUIDwtIGdlcmFyX2RhZG9zX2NvbXBsZXRvc19TTUFSVChkYWRvc19icnV0b3NfU01BUlQpCgpoZWFkKGRhZG9zX2NvbXBsZXRvc19TTUFSVCkKZHBseXI6OmdsaW1wc2UoZGFkb3NfY29tcGxldG9zX1NNQVJUKQpgYGAKClBhcmEgZ2FyYW50aXIgYSByZXByb2R1dGliaWxpZGFkZSBkb3MgY8OzZGlnb3MgcHJvZHV6aWRvcyBlbSB2ZXJzw7VlcyBhdHVhbGl6YWRhcyBkYSBiYXNlIGRlIGRhZG9zIGRvIE1vbml0b3JhLCDDqSBpbXBvcnRhbnRlIHRvbWFyIGFsZ3VucyBjdWlkYWRvcy4gTyBwcmltZWlybyBlIG1haXMgaW1wb3J0YW50ZSBjdWlkYWRvIMOpICoqbWFudGVyIGEgY29uc2lzdMOqbmNpYSBkb3Mgbm9tZXMsIGRhIG9yZGVtIGUgZG8gbsO6bWVybyBkZSBjb2x1bmFzKiogZW0gdmVyc8O1ZXMgYXR1YWxpemFkYXMgZGEgYmFzZSBkZSBkYWRvcyBkbyBNb25pdG9yYS4gQWzDqW0gZGUgY2FycmVnYXIgb3MgZGFkb3MsIGEgZnVuw6fDo28gYGNhcnJlZ2FyX2RhZG9zX2NvbXBsZXRvcygpYCBhcGxpY2EgdW1hIHPDqXJpZSBkZSB0cmFuc2Zvcm1hw6fDtWVzIG5hcyBjb2x1bmFzLiBTZXVzIG5vbWVzIHPDo28gYWx0ZXJhZG9zLCBlIGEgZXNzYXMgc8OjbyBhdHJpYnXDrWRvcyB0aXBvcyBhcHJvcHJpYWRvcyAoZGF0YSwgY2FyYWN0ZXIsIGZhdG9yLCBpbnRlaXJvIGUgbnVtw6lyaWNvKSwgbGluaGFzIHPDo28gZWxpbWluYWRhcyBlIG5vdmFzIGNvbHVuYXMgc8OjbyBnZXJhZGFzLiBRdWFscXVlciBhbHRlcmHDp8OjbyBubyBuw7ptZXJvIGRlIGNvbHVuYXMsIG5vcyBzZXVzIG5vbWVzIG91IG5hIHN1YSBvcmRlbSBsZXZhcsOhIGEgdW0gbWFsIGZ1bmNpb25hbWVudG8gZGEgZnVuw6fDo28gZGUgdHJhbnNmb3JtYcOnw6NvIGRvcyBkYWRvcy4KCk91dHJvcyBhc3BlY3RvcyBpbXBvcnRhbnRlcyBpbmNsdWVtOiAKCi0gYSBwcmVzZW7Dp2EgZGUgZGFkb3MgYXVzZW50ZXMgKGBOQWBzKSBzw6NvIGF1dG9tYXRpY2FtZW50ZSBzdWJzdGl0dWlkYXMgcGVsbyB2YWxvciBjb3JyZXRvIGFwZW5hcyBuYXMgY29sdW5hcyBgbm9tZV9lYWAsIGBlc2ZvcmNvX2RpYWAgZSBgdGVtcG9fc2Vuc29gOwoKLSBub3ZvcyBkYWRvcyBkZXZlbSBzZXIgYWRpY2lvbmFkb3MgYSBwbGFuaWxoYSBkZSBkYWRvcyB1dGlsaXphZGEgY29tbyBtb2RlbG8gbm8gcHJlc2VudGUgZG9jdW1lbnRvIChpZMOqbnRpY28gYW8gbW9kZWxvIGRvIG1vaW50b3JhKTsKCi0gc2Ugbm92YXMgVW5pZGFkZXMgZGUgQ29uc2VydmHDp8OjbyBwYXJhIGFsw6ltIGRhcyA0MSBwcmVzZW50ZXMgbmVzc2EgcGxhbmlsaGEgZm9yZW0gYWRpY2lvbmFkYXMsIGEgZnVuw6fDo28gcG9kZSBkZWl4YXIgZGUgZnVuY2lvbmFyLiBOZXNzZSBjYXNvLCBlbnRyZSBlbSBjb250YXRvIGNvbSBvcyBkZXNlbnZvbHZlZG9yZXMgdmlhIGUtbWFpbDogdm50Ym9yZ2VzanJAZ21haWwuY29tOwoKLSBvcyBub21lcyBkb3Mgb2JzZXJ2YWRvcmVzIGRldmVtIHNlciBzZXBhcmFkb3MgcG9yICIgZSAiLCAiIEUgIiwgIi8iLCAiOyIsIG91ICIgYSAiLiBOb3RlIHF1ZSwgcXVhbmRvIHByZXNlbnRlcywgb3MgZXNwYcOnb3Mgc8OjbyBpbXBvcnRhbnRlcyBlIGRldmVtIHNlciBhcGxpY2Fkb3MgcGFyYSBzZXBhcmHDp8OjbyBkb3Mgbm9tZXM7CgotIG5hIGNvbHVuYSBgdmFsaWRhY2FvYCAoY29sdW5hICJPIHF1ZSBmb2kgaWRlbnRpZmljYWRvIiBuYSBwbGFuaWxoYSBvcmlnaW5hbCkgZXNww6ljaWUgZGV2ZSBzZXIgaWRlbnRpZmljYWRvIGNvbW8gIkUiLCAiZSIsIG91ICJlc3DDqWNpZSI7IGfDqm5lcm8gZGV2ZSBzZXIgaWRlbnRpZmljYWRvIGNvbW8gIkciLCAiZyIsIG91ICJnw6puZXJvIjsgZmFtw61saWEgZGV2ZSBzZXIgaWRlbnRpZmljYWRhIGNvbW8gIkYiOyBlIG9yZGVtIGRldmUgc2VyIGlkZW50aWZpY2FkYSBjb21vICJPIjsKCi0gZGV2ZSBzZXIgdXRpbGl6YWRvIHBvbnRvIGNvbW8gc2VwYXJhZG9yIGRlY2ltYWwgKGFvIGVtIHZleiBkZSB2w61yZ3VsYSkuCgpBIHBhcnRpciBkZSBhZ29yYSBvcyBkYWRvcyBlc3TDo28gcHJvbnRvcyBwYXJhIHNlcmVtIGV4cGxvcmFkb3MsIG91ICBtZXNtbyBmaWx0cmFkb3MgZSB0cmFuc2Zvcm1hZG9zIHBhcmEgbyBmb3JtYXRvIGRvIHBhY290ZSBgRGlzdGFuY2VgIHBhcmEgYW7DoWxpc2UgZGUgZGVuc2lkYWRlLiBQb3IgZXhlbXBsbywgZmlsdHJhciBvcyBkYWRvcyBwYXJhIGEgVUMgY3Vqb3Mgb3MgZGFkb3MgZm9yYW0gaW50cm9kdXppZG9zIGEgcGFydGlyIGRvIFNNQVJUOgoKYGBge3J9CiMgY2FycmVnYXIgZnVuw6fDo28gZGUgZmlsdHJhZ2VtIGRvcyBkYWRvcwpzb3VyY2UoaGVyZTo6aGVyZSgiUi9maWx0cmFyX2RhZG9zLlIiKSkKCiMgZmlsdHJhciBkYWRvcyBwb3IgVW5pZGFkZSBkZSBDb25zZXJ2YcOnw6NvIGUgcG9yIGVzcMOpY2llCmRhZG9zX2ZpbHRyYWRvc19TTUFSVCA8LSBmaWx0cmFyX2RhZG9zKAogIGRhZG9zID0gZGFkb3NfY29tcGxldG9zX1NNQVJULAogIG5vbWVfdWNzID0gInJkc191YXR1bWEiCikKCmhlYWQoZGFkb3NfZmlsdHJhZG9zX1NNQVJUKQpzdHIoZGFkb3NfZmlsdHJhZG9zX1NNQVJUKQpgYGAKCkFnb3JhLCBwb2RlbW9zIGNvbnRhciBvIG7Dum1lcm8gZGUgb2JzZXJ2YcOnw7VlcyB2YWxpZGFkYXM6CgpgYGB7cn0KIyBjYXJyZWdhciBhIGZ1bsOnw6NvIGRlIGNvbnRhZ2VtIGRhcyBvYnNlcnZhw6fDtWVzIHZhbGlkYWRhcwpzb3VyY2UoaGVyZTo6aGVyZSgiUi9jb250YXJfbl9vYnNfdmFsaWRhZGFzLlIiKSkKCiMgY29udGFyIG9ic2VydmHDp8O1ZXMgdmFsaWRhZGFzIGFvIG7DrXZlbCBkZSBlc3DDqWNpZQpuX29ic192YWxpZGFkYXMgPC0gY29udGFyX25fb2JzX3ZhbGlkYWRhcyhkYWRvc19maWx0cmFkb3NfU01BUlQpCm5fb2JzX3ZhbGlkYWRhcwpgYGAKClZhbW9zIHNlbGVjaW9uYXIgdW1hIGVzcMOpY2llIGRhIFJEUyBVYXR1bcOjIHBhcmEgZW50w6NvIHRyYW5zZm9ybWFyIG9zIGRhZG9zIHBhcmEgbyBmb3JtYXRvIGRlIGFuw6FsaXNlIGRvIHBhY290ZSBgRGlzdGFuY2VgLiBQcmltZWlybyB2YW1vcyBhdmFsaWFyIHF1YWwgZm9pIGEgZXNww6ljaWUgbWFpcyBhYnVuZGFudGU6CgpgYGB7cn0KIyBjYXJyZWdhciBhIGZ1bsOnw6NvIHBhcmEgY29udGFyIG7Dum1lcm8gZGUgb2JzZXJ2YcOnw7VlcyBwb3IgZXNww6ljaWUgZSBwbG90YXIgb3MgZGFkb3MKc291cmNlKGhlcmU6OmhlcmUoIlIvY29udGFyX25fb2JzX3NwLlIiKSkKc291cmNlKGhlcmU6OmhlcmUoIlIvcGxvdGFyX25fb2JzX3NwX2ludGVyYXRpdm8uUiIpKQoKIyBjb250YXIgbyBuw7ptZXJvIGRlIG9ic2VydmHDp8O1ZXMgcG9yIGVzcMOpY2llCm5fb2JzX3NwIDwtIGNvbnRhcl9uX29ic19zcChkYWRvc19maWx0cmFkb3NfU01BUlQpCm5fb2JzX3NwCgojIHBsb3RhciBvIG7Dum1lcm8gZGUgb2JzZXJ2YcOnw7VlcyBwb3IgZXNww6ljaWUKcGxvdGFyX25fb2JzX3NwX2ludGVyYXRpdm8obl9vYnNfc3ApCmBgYAoKQSBlc3DDqWNpZSBtYWlzIGFidW5kYW50ZSBmb2kgKkNyeXB0dXJlbGx1cyogc3AuIFZhbW9zIGZpbHRyYXIgb3MgZGFkb3Mgc29tZW50ZSBwYXJhIGVzc2UgZXNww6ljaWU6CgpgYGB7cn0KZGFkb3NfZmlsdHJhZG9zX2NyeXB0X1NNQVJUIDwtIGZpbHRyYXJfZGFkb3MoCiAgZGFkb3MgPSBkYWRvc19maWx0cmFkb3NfU01BUlQsCiAgbm9tZV9zcHMgPSAiY3J5cHR1cmVsbHVzIgopCgpoZWFkKGRhZG9zX2ZpbHRyYWRvc19jcnlwdF9TTUFSVCkKc3RyKGRhZG9zX2ZpbHRyYWRvc19jcnlwdF9TTUFSVCkKYGBgCgpGaW5hbG1lbnRlLCB2YW1vcyB0cmFuc2Zvcm1hciBvcyBkYWRvcyBwYXJhIG8gZm9ybWF0byBkZSBhbsOhbGlzZToKCmBgYHtyfQojIGNhcnJlZ2FyIGZ1bsOnw6NvIGRlIHRyYW5zZm9ybWHDp8OjbyBkb3MgZGFkb3MgcGFyYSBvIGZvcm1hdG8gZG8gcGFjb3RlIERpc3RhbmNlCnNvdXJjZShoZXJlOjpoZXJlKCJSL3RyYW5zZm9ybWFyX2RhZG9zX2Zvcm1hdG9fRGlzdGFuY2UuUiIpKQoKIyB0cmFuc2Zvcm1hciBkYWRvcyBwYXJhIG8gZm9ybWF0byBkbyBwYWNvdGUgRGlzdGFuY2UKZGFkb3NfdHJhbnNmb3JtYWRvc19TTUFSVCA8LSB0cmFuc2Zvcm1hcl9kYWRvc19mb3JtYXRvX0Rpc3RhbmNlKGRhZG9zX2ZpbHRyYWRvc19jcnlwdF9TTUFSVCkKCmhlYWQoZGFkb3NfdHJhbnNmb3JtYWRvc19TTUFSVCkKZHBseXI6OmdsaW1wc2UoZGFkb3NfdHJhbnNmb3JtYWRvc19TTUFSVCkKYGBgCgo=